
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//#include "type.h"
#include "ccas.h"

int ccas_push(string *L1,int c1)
{
    string m1 = (string)malloc(sizeof(node1));
    if (m1 == NULL) return 1;
    memset(m1, 0, sizeof(node1));

    m1->data[0] = c1;
    m1->len=1;
    m1->next=*L1;
    m1->prev=NULL;

    if (*L1 != NULL) (*L1)->prev=m1;
    *L1=m1;

    return 0;
}

int ccas_insert(string *L1, int C1)
{
    if (*L1 == NULL) return ccas_push(L1,C1);
    if ((*L1)->len == CCAS_LENGTH)
        return ccas_push(L1,C1);
    (*L1)->data[(*L1)->len++] = C1;
    return 0;
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               }

void ccas_free(string* L1)
{
    if (*L1 == NULL) return;
    if ((*L1)->next != NULL)
        ccas_free(&(*L1)->next);
    free(*L1); //*L1=NULL;
}

string ccas_tail(string L1)
{
    if (L1 == NULL) return NULL;
    while(L1->next != NULL) L1 = L1->next;
    return L1;
}
//----------------------------------------------
/* ���������������� */
size_t ccas_find(string M, int T) {
    size_t ret = 0;
    string cur = M;
    while (cur) {
        for (int i = cur->len - 1; i > -1; --i) {
            if (cur->data[i] == T) {
                return ret +  i;
            }
        }
        ret += cur->len;
        cur = cur->next;
    }
    return -1;
}
/*
 { 9 8 }
 { 7 6 }
 { 5 4 }
 { 3 2 }
 { 1 0 }
*/
int ccas_ninsert(string* M, size_t pos, int item) {
    if (!*M && pos == 0) return ccas_push(M, item);
    string cur = *M, tmp = NULL;
    size_t myTarget = pos; //���巨
    while (cur) {

        if (cur->len > myTarget && cur->len == CCAS_LENGTH) { // Ҫ���뵽һ�����ĸ�����
            size_t thisPos = myTarget;
            string T = NULL;
            for (int i = thisPos; i < cur->len; ++i) {
                ccas_insert(&T, cur->data[i]);
            }
            T->next = cur->next;
            cur->len = thisPos;
            cur->next = T;
            ccas_insert(&cur, item);
            return item;
        }

        else if (cur->len > myTarget && cur->len < CCAS_LENGTH) { // Ҫ���뵽һ�������ĸ�����
            size_t thisPos = myTarget;
            for (int i = cur->len; i > thisPos; --i) {
                cur->data[i] = cur->data[i - 1];
            }
            cur->data[thisPos] = item;
            cur->len++;
            return item;
        }

        else if (cur->len <= myTarget) {
            myTarget -= cur->len;
        }
        tmp = cur;
        cur = cur->next;

    }
    return EOF;
}

size_t ccas_print(string M) {
    string cur = M;
    size_t ret = 0;
    while (cur) {
        for (int i = 0; i < cur->len; ++i) {
            ret++;
            printf("%d ", cur->data[i]);
        }
        cur = cur->next;
    }
    printf("\n");
    return ret;
}

int ccas_pop(string* M) {
    string T = *M;
    int ret = T->data[--T->len];
    if (T->len == 0) {
        *M = T->next;
        free(T);
    }
    return ret;
}

//----------------------------------------------
/* ������CCAS���� */

string ccas_r()
{
    string m1 = NULL;
    int c;
    while('\n' != (c = getchar()) &&  0 == ccas_insert(&m1, (char)c));
    if (c == '\n') return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_rs(char* CS1)
{
    string m1 = NULL;
    char *p1 = CS1;
    while('\0' != *p1  &&  ccas_insert(&m1, *(p1++)) == 0)
    {
        //printf("%c\n",*p1);
    }
    if (*p1 == '\0') return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_as(string *s1, const char *c1)
{
    const char *p1 = c1;
    while('\0' != *p1  &&  ccas_insert(s1, *(p1++)) == 0)
    {
        //printf("%c",*p1);
    }
    if (*p1 == '\0') return *s1;
    else {
        ccas_free(s1);
        return NULL;
    }
}

string ccas_rf(char* path)
{
    FILE* f = fopen(path, "r");
    if (!f) return NULL;

    string m1 = NULL;
    int c;
    while( (c=fgetc(f)) != EOF && ccas_insert(&m1, (char)c) == 0);
    fclose(f);
    if ( c == EOF) return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_rf2(FILE* f1)
{
    string m1 = NULL;
    int c;
    while( (c=fgetc(f1)) != EOF && ccas_insert(&m1, (char)c) == 0);
    if ( c == EOF) return m1;
    else {
        ccas_free(&m1);
        return NULL;
    }
}

string ccas_rf3(int fd){
    string M = NULL;
    char buffer;
    int n = 0;
    while( 1 == (n = read(fd, &buffer, 1)) && ccas_insert(&M, buffer) == 0 )
        ;
    if (n != 1) return M;
    else {
        ccas_free(&M);
        return NULL;
    }
}

char* ccas_ws(string L1)
{
    char *cs1 = (char*)malloc(sizeof(char));
    if (!cs1) return NULL;

    
    *cs1 = '\0';
    if (!L1) return cs1;

    L1 = ccas_tail(L1);
    while(L1)
    {
        int lt1 = strlen(cs1);
        cs1 = (char*)realloc(cs1, lt1+1 + L1->len);
        if (cs1 == NULL) return NULL;

        int i=0;
        for (;i < L1->len; ++i){
            //printf("%c\n",L1->data[i]);
            cs1[lt1+i] = L1->data[i];
        }
        cs1[lt1+i] = '\0';
        L1 = L1->prev;
    }

    return cs1;
}

int ccas_wf(string L1, char* Path1)
{
    FILE *f = fopen(Path1, "w");
    if(!f) return 1;

    string l2 = ccas_tail(L1);
    while(l2 != NULL)
    {
        int i=0;
        for (;i < l2->len; ++i)
            fputc(l2->data[i], f);
        l2 = l2->prev;
    }

    fclose(f);
    return 0;
}
